import { _decorator, Component, EventTouch, Node, UITransform, Vec2, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('TouchJoystickBase')
export class TouchJoystickBase extends Component {
    @property(Node)
    protected ndPanel: Node = null;

    @property(Node)
    protected ndHandle: Node = null;

    protected _v2: Vec2 = new Vec2();
    protected _v3: Vec3 = new Vec3();
    protected _startPos: Vec3 = new Vec3();
    protected _currentPos: Vec3 = new Vec3();
    protected _radius: number = 0;

    protected onEnable(): void {
        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
    }

    protected onDisable(): void {
        this.node.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.off(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
    }

    protected start(): void {
        this._radius = this.ndPanel.getComponent(UITransform).contentSize.width / 2;
    }

    protected onTouchStart(event: EventTouch): void {
        event.getUIStartLocation(this._v2);
        this._v3.set(this._v2.x, this._v2.y, 0);
        this.node.getComponent(UITransform).convertToNodeSpaceAR(this._v3, this._startPos);
    }

    protected onTouchMove(event: EventTouch): void {
        event.getUILocation(this._v2);
        this._v3.set(this._v2.x, this._v2.y, 0);
        this.node.getComponent(UITransform).convertToNodeSpaceAR(this._v3, this._currentPos);
        this._updateHandlePosition();
    }

    protected onTouchEnd(): void {
        this._makePosition();
        this._onTouchFinish();
    }

    protected onTouchCancel(): void {
        this._makePosition();
        this._onTouchFinish();
    }

    protected _updateHandlePosition(): void {
        const distance = Vec2.distance(this._startPos, this._currentPos);
        const radian = Math.atan2(this._currentPos.y - this._startPos.y, this._currentPos.x - this._startPos.x);
        if (distance < this._radius) {
            this.ndHandle.setPosition(this._currentPos);
        } else {
            const x = this._startPos.x + Math.cos(radian) * this._radius;
            const y = this._startPos.y + Math.sin(radian) * this._radius;
            this.ndHandle.setPosition(x, y, 0);
        }
        this._changeRadian(radian);
        this._changeDistance(distance);
    }

    protected _makePosition(pos: Vec3 = Vec3.ZERO): void {
        this.ndPanel.setPosition(pos);
        this.ndHandle.setPosition(pos);
    }

    // 子类需要实现的抽象方法
    protected _onTouchFinish(): void { }
    protected _changeRadian(radian: number): void { }
    /** 处理传递范围 */
    protected _changeDistance(distance){}
}